package com.tsfyun.scm.service.impl.system;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.config.OrikaBeanMapper;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.system.SubjectBankDTO;
import com.tsfyun.scm.dto.system.SubjectBankQTO;
import com.tsfyun.scm.entity.base.Currency;
import com.tsfyun.scm.entity.customer.Customer;
import com.tsfyun.scm.entity.customer.Supplier;
import com.tsfyun.scm.entity.system.SubjectBank;
import com.tsfyun.scm.entity.system.SubjectOverseas;
import com.tsfyun.scm.mapper.system.SubjectBankMapper;
import com.tsfyun.scm.service.base.ICurrencyService;
import com.tsfyun.scm.service.system.ISubjectBankService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.service.system.ISubjectService;
import com.tsfyun.scm.vo.system.SubjectBankVO;
import com.tsfyun.scm.vo.system.SubjectVO;
import org.codehaus.groovy.util.ListHashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.WeekendSqls;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 *
 * @since 2020-03-20
 */
@Service
public class SubjectBankServiceImpl extends ServiceImpl<SubjectBank> implements ISubjectBankService {

    @Autowired
    private OrikaBeanMapper beanMapper;
    @Autowired
    private ICurrencyService currencyService;
    @Autowired
    private ISubjectService subjectService;
    @Autowired
    private SubjectBankMapper subjectBankMapper;


    @Override
    public void add(SubjectBankDTO dto) {
        dto.setIsDefault(Objects.equals(dto.getIsDefault(),true));
        dto.setReceivables(Objects.equals(dto.getReceivables(),true));
        Currency currency = currencyService.findByName(dto.getCurrencyName());
        TsfPreconditions.checkArgument(Objects.nonNull(currency),new ServiceException("所选币制不存在"));
        SubjectBank bank = beanMapper.map(dto,SubjectBank.class);
        //获取主体公司信息
        SubjectVO subjectVO = subjectService.findByCode();
        TsfPreconditions.checkArgument(Objects.nonNull(subjectVO),new ServiceException("主体公司未找到"));
        bank.setSubjectId(subjectVO.getId());
        bank.setDisabled(Boolean.FALSE);
        bank.setCurrencyId(currency.getId());
        //本条数据默认将其他数据设置非默认
        if(bank.getIsDefault()){
            SubjectBank update = new SubjectBank();
            update.setIsDefault(Boolean.FALSE);
            subjectBankMapper.updateByExampleSelective(update, Example.builder(SubjectBank.class).where(
                    WeekendSqls.<SubjectBank>custom().andEqualTo(SubjectBank::getSubjectId,bank.getSubjectId())
            ).build());
        }
        super.saveNonNull(bank);
    }

    @Override
    public void edit(SubjectBankDTO dto) {
        Currency currency = currencyService.findByName(dto.getCurrencyName());
        TsfPreconditions.checkArgument(Objects.nonNull(currency),new ServiceException("所选币制不存在"));
        SubjectBank update = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(update),new ServiceException("企业银行信息不存在"));
        update.setName(dto.getName());
        update.setAccount(dto.getAccount());
        update.setCurrencyId(currency.getId());
        update.setAddress(dto.getAddress());
        update.setIsDefault(Objects.equals(dto.getIsDefault(),true));
        update.setReceivables(Objects.equals(dto.getReceivables(),true));
        update.setMemo(dto.getMemo());
        //本条数据默认将其他数据设置非默认
        if(update.getIsDefault()){
            SubjectBank example = new SubjectBank();
            example.setIsDefault(Boolean.FALSE);
            subjectBankMapper.updateByExampleSelective(example, Example.builder(SubjectBank.class).where(
                    WeekendSqls.<SubjectBank>custom().andEqualTo(SubjectBank::getSubjectId,update.getSubjectId())
                    .andNotEqualTo(SubjectBank::getId,update.getId())
            ).build());
        }
        super.updateById(update);
    }

    @Override
    public PageInfo<SubjectBankVO> pageList(SubjectBankQTO qto) {
        PageHelper.startPage(qto.getPage(),qto.getLimit());
        List<SubjectBankVO> list = subjectBankMapper.pageList(qto);
        return new PageInfo(list);
    }

    @Override
    public SubjectBankVO detail(Long id) {
        SubjectBank subjectBank = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(subjectBank),new ServiceException("企业银行信息不存在"));
        SubjectBankVO bankVO = beanMapper.map(subjectBank,SubjectBankVO.class);
        bankVO.setCurrencyName(currencyService.findById(bankVO.getCurrencyId()).getName());
        return bankVO;
    }

    @Override
    public void updateDisabled(Long id, Boolean disabled) {
        SubjectBank subjectBank = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(subjectBank),new ServiceException("企业银行信息不存在"));
        SubjectBank update = new SubjectBank();
        update.setDisabled(disabled);
        subjectBankMapper.updateByExampleSelective(update, Example.builder(SubjectBank.class).where(
                WeekendSqls.<SubjectBank>custom().andEqualTo(SubjectBank::getId,id)
        ).build());
    }

    @Override
    public void remove(Long id) {
        SubjectBank subjectBank = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(subjectBank),new ServiceException("企业银行信息不存在"));
        try{
            super.removeById(id);
        } catch (DataIntegrityViolationException e) {
            throw new ServiceException("当前企业银行存在关联性数据，不允许删除");
        }
    }

    @Override
    public List<SubjectBankVO> selectEnableBanks() {
        SubjectBank condition = new SubjectBank();
        condition.setDisabled(Boolean.FALSE);
        List<SubjectBank> list = super.list(condition);
        if(CollUtil.isNotEmpty(list)) {
            List<SubjectBankVO> datas = beanMapper.mapAsList(list,SubjectBankVO.class);
            Map<Long,String> subjectMap = new ListHashMap<>();
            datas.stream().forEach(sb ->{
                String subjectName = subjectMap.get(sb.getSubjectId());
                if(StringUtils.isEmpty(subjectName)){
                    subjectName = subjectService.getById(sb.getSubjectId()).getName();
                    subjectMap.put(sb.getSubjectId(),subjectName);
                }
                sb.setSubjectName(subjectName);
            });
            return datas.stream().sorted(Comparator.comparing(SubjectBankVO::getIsDefault).reversed()).collect(Collectors.toList());
        }
        return Lists.newArrayList();
    }
    @Override
    public List<SubjectBankVO> selectReceivablesBanks(Long subjectId) {
        SubjectBank condition = new SubjectBank();
        condition.setDisabled(Boolean.FALSE);
        condition.setReceivables(Boolean.TRUE);
        condition.setSubjectId(subjectId);
        List<SubjectBank> list = super.list(condition);
        if(CollUtil.isNotEmpty(list)) {
            List<SubjectBankVO> datas = beanMapper.mapAsList(list,SubjectBankVO.class);
            return datas.stream().sorted(Comparator.comparing(SubjectBankVO::getIsDefault).reversed()).collect(Collectors.toList());
        }
        return Lists.newArrayList();
    }
}
